package com.paso;


/**
 * 定义一个SingleLinkedList来管理我们的英雄
 */
public class SingleLinkedList {

    /**
     * 定义一个头节点,不存放具体数据
     */
    private final HeroNode head = new HeroNode(0, "", "");

    public HeroNode getHead() {
        return head;
    }



    /**
     * 添加节点到链表的最后
     * 思路：当不考虑编号顺序时
     * 1.找到链表最后一个节点
     * 2.把最后一个节点的next指向新的节点
     *
     * @param heroNode 需要添加的节点
     */
    public void add(HeroNode heroNode) {
        // 定义一个辅助变量
        HeroNode temp = head;

        // 遍历链表找到最后
        while (temp.getNext() != null) {
            temp = temp.getNext();
        }

        // 当退出while循环时候，temp就指向链表的最后节点
        // 把最后一个节点的next指向新的节点
        temp.setNext(heroNode);
    }

    /**
     * 根据排名把英雄插入到指定位置
     */
    public void addByOrder(HeroNode heroNode) {
        // 定义一个辅助指针（变量）
        HeroNode temp = head;

        // 标志新插入的编号是否在链表中已经存在，默认不存在
        boolean flag = false;

        // 遍历链表
        while (true) {
            if (temp.getNext() == null) {
                break; //表示已经到链表的结尾了
            } else if (temp.getNext().getNo() == heroNode.getNo()) {
                flag = true;
                break;
            } else if (temp.getNext().getNo() > heroNode.getNo()) {
                break;
            }
            temp = temp.getNext();
        }

        if (flag) {
            System.out.printf("英雄%d已经存在于链表中，插入失败\n", heroNode.getNo());
        } else {
            // 插入节点到链表
            heroNode.setNext(temp.getNext());
            temp.setNext(heroNode);
        }

    }


    /**
     * 修改节点，根据节点编号来修改，节点编号不能修改
     *
     * @param newHeroNode 需要修改的节点
     */
    public void update(HeroNode newHeroNode) {

        // 定义一个辅助指针
        HeroNode temp = head;

        // 定义一个标识，默认为false，表示没有找到节点
        boolean flag = false;

        // 遍历链表
        while (true) {
            if (temp.getNext() == null) {
                break; // 表示遍历完了链表,退出循环
            }

            if (temp.getNext().getNo() == newHeroNode.getNo()) {
                flag = true; // 表示找了编号相同的节点
                break;
            }

            // 后移一位
            temp = temp.getNext();
        }

        if (flag) {
            temp.getNext().setName(newHeroNode.getName());
            temp.getNext().setNickname(newHeroNode.getNickname());
        }else {
            System.out.printf("没有找到编号%d的节点\n", newHeroNode.getNo());
        }
    }


    /**
     * 删除节点
     * @param heroNodeNo 需要删除的节点的编号
     */
    public void delete(int heroNodeNo){
        //head节点不能动，所以需要一个辅助节点
        HeroNode temp = head;

        // 定义一个标识，用来标记是否找到了需要删除的节点,默认为false，表示未找到
        boolean flag = false;

        // 遍历链表
        while (true){

            if (temp.getNext() == null){
                break; // 遍历结束了链表
            }

            // 这里比较的是编号，不能比较对象
            if (temp.getNext().getNo() == heroNodeNo){
                flag = true; // 找到了需要删除的节点
                break;
            }

            temp = temp.getNext();
        }

        if (flag){
            temp.setNext(temp.getNext().getNext());
        }else {
            System.out.printf("未找到编号为%d的节点\n",heroNodeNo);
        }
    }


    /**
     * 显示链表所有节点数据，不包括head节点
     */
    public void list() {
        HeroNode temp = head;

        // 判断链表是否为空
        if (head.getNext() == null) {
            System.out.println("链表为空");
            return;
        }

        while (temp.getNext() != null) {
            temp = temp.getNext();
            System.out.println(temp);
        }
    }

}
